;*************************************************************************************************
;*************************************************************************************************
;************************************ MIPS DOMACI APRIL 2010 *************************************
;*************************************************************************************************
;*************************************************************************************************
RES_TAB SEGMENT AT FFFF0H
	JMP Far ptr START
RES_TAB ENDS;         

DAT SEGMENT AT 0000h
	IDIV0		dw 	    2 DUP(?)	; deljenje nulom - ulaz 0
	ISS		dw 	    2 DUP(?)	; single step - ulaz 1
	INMI		dw 	    2 DUP(?)	; nemaskirajuci prekid - ulaz 2           
	BR          	dw          2 DUP(?)    ; breakpoint - ulaz 3
	OVERFLOW    	dw          2 DUP(?)    ; overflow - ulaz 4
    	Ireserved 	dw    	   54 DUP(?)    ; rezervisani prekidi do ulaza 32, od ulaza 32 pocinju slobodne lokacije u IVT
    	I8259 		dw         16 DUP(?)  	; 8 ulaza za prekide od 8259A - kontroler prekida, jer ima vise od jednog tipa prekida u sistemu
    	Irest 		dw        432 DUP(?)    ; rezervise se prostor za preostale ulaze
;************************************************************************************
; PROMENJIVE
;************************************************************************************   
msec		dw	0000h			; kad clock odbroji sa 1000 na 0 azuriramo sat 
sati		db	00h     		; pocetno vreme - (sati)   
min		db	00h     		; pocetno vreme - (min)  
sec		db	00h     		; pocetno vreme - (sec)
tempSec		db	00h			; pamti vreme koje je kasnije potrebno	     

currState   	db  	0           		; tekuce stanje
      
kupljenProizvod db	0			; da li je proizvod kupljen ili ne
broj_poruke     db  	0           		; broj primljenih bajtova sa serijskog porta (NUM RECEIVED PACKAGES) 
promet_u       	dw  	0           		; ukupan promet svih proizvoda
Hpromet      	db  	0          		; visi bajt reci za promet proizvoda
broj_proizvoda  db  	0          		; redni broj proizvoda   

trenutni_ispis 	db	8 DUP(00h)  		; trenutni ispis na display
trenutno_vreme  db 	8 DUP(00h)  		; trenutni vreme za display
trenutna_poruka	db	8 DUP(00h)  		; trenutni poruka za display
poruka	    	db	20 DUP(00h) 		; trenutna poruka 
len         	db  	0           		; duzina trenutne poruke 
uneto_cifara    db  	0   			; broj unetih cifara
prikazuj_vip	db	0			; sta da se trenutno ispisuje na displej(poruka, ispis, vreme)
trenutni_karakter db	0			; karakter koji se prikazuje na displeju 

suma    	dw  0           		; kolicina ubacenog novca 
novcanica_izbacena    dw  0           		; kusur koji se vraca   
nema_novcanica  db  0           		; indikator da nema novcanice
no200       	db  0          			; indikator da nema 200
no100       	db  0           		; indikator da nema 100
no50        	db  0           		; indikator da nema 50
no20        	db  0           		; indikator da nema 20
no10        	db  0           		; indikator da nema 10

prod        	db 0            		; da li ima proizvoda(0-ima,1-nema)
tmpChar     	db 0            		; trenutni karakter koji je unesen sa tastature  
brojac       	db 0            		; do kog karaktera sam stigao u ispisu na display
cifra1    	db 0           			; kod 1. karaktera 
cifra2    	db 0           			; kod 2. karaktera     

motorNum    	db 0		                ; broj motora koji treba da se pokrene   

znakovi     	db 26  DUP(00h)
brojevi     	db 10  DUP(00h)

cenaProizvoda  	db 100 DUP(00h)     		; cene proizvoda  
zaradaProizvoda dw 100 DUP(0000h)  		;promet proizvoda
nazivProizvoda  db  2000 DUP(00h)   		;imena proizvoda  100*20byte 

oneMS       	db  0           		; indikator da je prosla 1ms

        
;*************************************************************************************************
; PORUKE ZA ISPIS NA DISPLAY
;*************************************************************************************************      
nestaloP	db	'N','E','S','T','A','O',' ','I','Z','A','B','E','R','I','D','R','U','G','I',' '  
uzmiteK	    	db	'U','Z','M','I','T','E',' ','K','U','S','U','R',' ',' ',' ',' ',' ',' ',' ',' '  
nestaloN	db	'N','E','S','T','A','L','O',' ','N','O','V','C','A','N','I','C' 'A' ',' ',' ' ' 
zahvalnost	db	'H','V','A','L','A',' ','N','A',' ','K','O','R','I','S','C','E','N','J','U',' '
potvrda		db	'P','O','T','V','R','D','I','T','E',' ','S','A',' ','E','N','T','E','R',' ',' ' 
nestaloP	db	'N','E','D','O','V','O','L','J','N','O',' ','N','O','V','C','A',' ',' ',' ',' '
,
;*************************************************************************************************
; STANJA
;*************************************************************************************************  
STARTNO_STANJE	            EQU	0 
AWAIT_PROCUDT 	            EQU 1 
CONFIRM_PRODUCT	            EQU 2
POSTAVI_NAZIV_CENU	    EQU 3
POSTAVI_CENU		    EQU 4
PROCITAJ_PROMET_U	    EQU 5
PROCITAJ_PROMET_P	    EQU 6
RESETUJ_PROMET_P	    EQU 7
RESETUJ_PROMET_U	    EQU 8
PODESAVANJE_VREMENA	    EQU 9

	                                                                                                                                         
;*************************************************************************************************	
;Definisanje 8251
;*************************************************************************************************                                                                                      
DAT8251     EQU 4000h  				; data address
CON8251     EQU 4002h  				; control & status address 
      
MW8251      EQU 01001110b
;  0  1  0  0  1  1  1  0 
;   \  \  \  \  \  \  \__\______________________ baud rate factor of 16x
;    \  \  \  \  \__\___________________________ character length of 8 bits
;     \  \  \__\________________________________ parity disabled  
;      \__\_____________________________________ 1 stop bits										
CW8251      EQU 00110111b			
;  0  0  1  1  0  1  1  1 
;   \  \  \  \  \  \  \  \______________________ transmit enable
;    \  \  \  \  \  \  \________________________ Data Terminal Ready, DTR will output 0
;     \  \  \  \  \  \__________________________ receive enable
;      \  \  \  \  \____________________________ normal operation
;       \  \  \  \______________________________ reset all error flags
;        \  \  \________________________________ RTS output 0, Request To Send
;         \  \__________________________________ do not return to mode instruction form
;          \____________________________________ disable hunt mode

      
;**************************************************************************************************	
;Definisanje 8254
;**************************************************************************************************
CA8254 	    EQU 5000h 				; Counter 0 - Koristi se za merenje 1ms koja je potrebna za 				
                        			; brojanje vremena , na ulaz CLK ide PCLK, broji non-stop .					
                        			;
CB8254 	    EQU 5002h 				; Counter 1 - Koristi se za merenje 1ms koja je potrebna za
                        			; cekanje automata , na ulaz CLK ide PCLK (polovina takta 					
                        			; CPUa), na ulaz GATE ide signal RD ili WR koji je indikator 				
                        			; da treba da pocne odbrojavanje 1ms. 
CC8254 	    EQU 5004h 				; Counter 2 -Koristi se za generisanje prijemnog i predajnog 
                        			; takta za 8251, na ulaz CLK ide PCLK, na ulaz GATE ide +5V.  				
                        			;
CON8254     EQU 5006h				; Control word address   

LSBA8254    EQU 58h 				; vrednost za Counter 0 LSB - 2457600 / 1000 = 2458 											
MSBA8254    EQU 24h 				; vrednost za Counter 0 MSB 
																				
LSBB8254    EQU 10h 				; Counter 2 - 2457600 / (16*9600) = 16 = 10h , 9600 je baud rate, a 16 baud rate factor

LSBC8254    EQU 58h 				; vrednost za Counter 1 LSB - 2457600 / 1000 = 2458												
MSBC8254    EQU 24h 				; vrednost za Counter 1 MSB


MODA8254 	EQU 00110100b
;  0  0  1  1  0  1  0  0 
;   \  \  \  \  \  \  \  \______________________ Binary Counter 16-bits
;    \  \  \  \  \__\__\________________________ Mode 2
;     \  \  \__\________________________________ LSB pa MSB
;      \__\_____________________________________ Select Counter 0							
                                                                                                                              
MODB8254 	EQU 01110100b
;  0  1  0  1  0  1  0  0 
;   \  \  \  \  \  \  \  \______________________ Binary Counter 16-bits
;    \  \  \  \  \__\__\________________________ mode 2
;     \  \  \__\________________________________ LSB ps MSB
;      \__\_____________________________________ Select Counter 1    

MODC8254 	EQU10110110b
;  1  0  1  1  0  1  1  0 
;   \  \  \  \  \  \  \  \______________________ Binary Counter 16-bits
;    \  \  \  \  \__\__\________________________ Mode 3
;     \  \  \__\________________________________ LSB pa MSB
;      \__\_____________________________________ Select Counter 2


;***********************************************************************************	
;Definisanje 8255
;***********************************************************************************
PA8255 		EQU 6000h		; port A
PB8255 		EQU 6002h		; port B
PC8255 		EQU 6004h		; port C     

CON8255 	EQU 6006h		; kontrolni registar 

MOD8255 	EQU 10000010b
;  1  0  0  0  0  0  1  1 
;   \  \  \  \  \  \  \  \______ Port C(Lower) input
;    \  \  \  \  \  \  \________ Port B input
;     \  \  \  \  \  \__________ Mode 0
;      \  \  \  \  \____________ Port C(Upper) output
;       \  \  \  \______________ Port A output
;        \  \__\________________ Mode 0
;         \ ____________________ Mode set flag


;************************************************************************************	
;Definisanje 8259
;************************************************************************************ 
A8259 		EQU 7000h			; lower address						
B8259 		EQU 7002h			; higher address	

ICW1 		EQU 00010111b
;  0  0  0  1  0  1  1  1 
;   \  \  \  \  \  \  \  \_____________________ ICW4 potrebna
;    \  \  \  \  \  \  \_______________________ samo jedan 8259 kontroler
;     \  \  \  \  \  \_________________________ za 8086 nebitan , stavljamo 1
;      \  \  \  \  \___________________________ 0 okidanje na ivicu
;       \  \  \  \_____________________________ 1
;        \__\__\_______________________________ za 8086 nebitan , stavljamo 0

ICW2 		EQU 32h         		; adrese prekidnih rutina su pocev od 32-og ulaza u 						
                                		; tabeli prekidnih rutina, tj. od 128. adrese

ICW4 		EQU 00000011b
;  0  0  0  0  0  0  1  1 
;   \  \  \  \  \  \  \  \______________________ 8086/8080 mode
;    \  \  \  \  \  \  \________________________ auto EOI(end of interrupt)
;     \  \  \  \  \__\__________________________ non buffered mode
;      \  \  \  \_______________________________ not special fully nested mode
;       \__\__\_________________________________ 0

     
;******************************************************************************************************	
;Definisanje ROM 
;******************************************************************************************************                
program SEGMENT AT 0FC000h                    	; na pocetak rom memorije
ASSUME CS:program,  DS:data, ES:data, SS:data 	; u sistemu ima samo program i data segmente, stek je na kraju data segmenta 


;******************************************************************************************************	
;Inicijalizacija 8251
;******************************************************************************************************
init8251 proc Near										
	    MOV DX, CON8251		; pretpostavicemo da urešaj ocekuje MODE instrukciju, 
	    MOV AL, 00h			; pa cemo ga inicijalizovati u sinhroni rezim rada
	    OUT DX, AL			; sa 2 sinhronizaciona karaktera , ovo postizemo	
	    MOV CX, 2			; upisom na kontrolnu adresu	3 uzastopna bajta kojim	
D0:	    LOOP D0			; su vrednosti svih bita **************************** 0
	    OUT DX, AL								
	    MOV CX, 2								
D1:	    LOOP D1						
	    OUT DX, AL											
	    MOV CX, 2											
D2:	    LOOP D2											
	    MOV AL, 40h			; zatim softverski resetujemo urešaj, tako sto saljem
	    OUT DX, AL			; COMMAND instrukciju, u kojoj bit D6 ima vrednost 1	
	    MOV CX, 2							
D3:	    LOOP D3									
	    MOV AL, MW8251 		; zatim ucitavamo mode i control word		
	    OUT DX, AL											
	    MOV CX, 2									
D4:	    LOOP D4												
	    MOV AL, CW8251					
	    OUT DX, AL		    										
	    RET												
init8251 endp


;****************************************************************************************************	
;Inicijalizacija 8254
;****************************************************************************************************
init8254 proc Near										
	    MOV DX, CON8254			
	    MOV AL, MODA8254		
	    OUT DX, AL		
	    MOV AL, LSBA8254		
	    MOV DX, CA8254			
	    OUT DX, AL		
            MOV AL, MSBA8254		
	    OUT DX, AL							
		
    	    MOV AL, MODB8254		
    	    MOV DX, CON8254			
    	    OUT DX, AL		
    	    MOV AL, LSBB8254	
    	    MOV DX, CB8254			
    	    OUT DX, AL	      
    	    	
    	    MOV AL, MODC8254		
    	    OUT DX, AL		
    	    MOV AL, LSBC8254		
    	    MOV DX, CC8254			
    	    OUT DX, AL		
            MOV AL, MSBC8254		
    	    OUT DX, AL																							
	    RET					
init8254 endp

  
;*************************************************************************************************	
;Inicijalizacija 8255
;************************************************************************************************* 
init8255 proc Near	
        MOV DX, CON8255	
        MOV AL, MOD8255	
        OUT DX, AL		
        RET		
init8255 endp


;*************************************************************************************************	
;Inicijalizacija 8259
;************************************************************************************************* 
init8259 proc Near	
        MOV DX, A8259			
        MOV AL, ICW1	
        OUT DX, AL				
        MOV DX, B8259			
        MOV AL, ICW2			
        OUT DX, AL				
        MOV AL, ICW4			
        OUT DX, AL				
        RET					
init8259 endp

  
;*************************************************************************************************	
;Prekid za Timer0 brojanje vemena
;*************************************************************************************************  
brojacVremenaInt Proc far 
        CLI  
        PUSHA         
        
        MOV AX, msec
        INC AX 
        MOV msec, AX
        CMP AX, 3E8h 
        JNZ DISPL            ; ako nije doslo do 1000 skoci na kraj i msec++
        MOV msec,0000h     
        
        MOV AL, sec
        INC AL 
        MOV sec, AL
        CMP AL, 3Ch 
        JNZ DISPL 
        MOV sec,00h        
                   
        MOV AL, min
        INC AL 
        MOV min, AL
        CMP AL, 3Ch 
        JNZ DISPL 
        MOV min,00h 
        
        MOV AL, sati
        INC AL 
        MOV sati, AL
        CMP AL, 18h 
        JNZ DISPL 
        MOV sati,00h   
DISPL:	CALL formiraj_vreme
	MOV AL, trenutni_karakter
	ADD AL,1
	CMP AL,7
	JLE DISPL1
	MOV AL, 0
DISPL1:	MOV trenutni_karakter, AL
        MOV DX, PA8255 		; u DX ide adresa porta a iz 8255
        OUT DX, AL		; upise se vrednost
	MOV AL, 01000000b
	MOV DX, PC8255
	OUT DX, AL
	MOV AL, 00000000b
	MOV DX, PC8255
	OUT DX, AL		
	MOV BL, prikazuj_vip
	CMP BL, 0
	JNE DISPL2
	MOV CL, trenutno_vreme[AL]
	JMP DISPLE
DISPL2:	CMP BL,1
	JNE DISPL3
	MOV CL, trenutni_ispis[AL]
	JMP DISPLE	
DISPL3: MOV CL, trenutna_poruka[AL]

DISPLE: MOV DX, PA8255 		; u DX ide adresa porta a iz 8255
        OUT DX, CL		; upise se vrednost
	MOV BL, 01000000b
	MOV DX, PC8255
	OUT DX, BL
	MOV BL, 00000000b
	MOV DX, PC8255
	OUT DX, BL
	      
KRAJ:   POPA
        STI
        IRET
brojacVremenaInt EndP


   
;****************************************************************************************************	
;Prekid za Timer1 brojanje 1ms
;****************************************************************************************************
timer1Int Proc far 
        CLI  
        PUSHA 
        
        MOV oneMS,1
         
        POPA
        STI
        IRET 
timer1Int EndP


;****************************************************************************************************	
;Procedura za cekanje 1ms 
;**************************************************************************************************** 
cekaj_1msec Proc Near
    
                                 
WHILEW:MOV AL, oneMS
       CMP AL, 1
       JNE WHILEW
       
       MOV oneMS,0                                 
 
       RET
cekaj_1msec EndP

    
;****************************************************************************************************	
;Procedura za formiranje ispisa koji se prikazuje na displej
;****************************************************************************************************
formiraj_ispis Proc Near        
        CLI    
                       
        MOV AL, uneto_cifara
        CMP AL, 2                                                     
        JNE JEDNA
        MOV AL, cifra1
        MOV trenutni_ispis[0], AL
        MOV AL, cifra2
        MOV trenutni_ispis[1], AL
JEDNA:  MOV AL, uneto_cifara
        CMP AL, 1
        JNE NIJED
        MOV AL, cifra1
        MOV trenutni_ispis[0], AL
        MOV trenutni_ispis[1], ' '
NIJED:  MOV trenutni_ispis[0], ' '
        MOV trenutni_ispis[1], ' '
           
        MOV trenutni_ispis[2], ' '    
        MOV trenutni_ispis[3], ' '                                         

        MOV AX, suma
        MOV BL, 10
        DIV BL         			; AL = rez , AH = ostatak       
        MOV trenutni_ispis[7], AH     
                                   
        
        MOV AH, 0
        MOV BL, 10
        DIV BL         			; AL = rez , AH = ostatak       
        MOV trenutni_ispis[6], AH 
        
      
        MOV AH, 0
        MOV BL, 10
        DIV BL         			; AL = rez , AH = ostatak       
        MOV trenutni_ispis[5], AH  
        
        
        MOV AH, 0
        MOV BL, 10
        DIV BL         			; AL = rez , AH = ostatak       
        MOV trenutni_ispis[4], AH             
        
        MOV AL, trenutni_ispis[4]    	; da li je mozda u trenutni_ispis[4]nula
        CMP AL, 0         		;ako jeste onda stavi prazninu
        JNE KRAJFI  
        MOV trenutni_ispis[4], ' '
        MOV AL, trenutni_ispis[5]
        CMP AL, 0
        JNE KRAJFI 
        MOV trenutni_ispis[5], ' '
KRAJFI: STI
        RET
formiraj_ispis EndP
 

;****************************************************************************************************	
;Procedura za formiranje vremena koje se prikazuje na displej
;****************************************************************************************************
formiraj_vreme Proc Near
        
        MOV trenutno_vreme[2], 58     	; dvotacke za vreme
        MOV trenutno_vreme[5], 58    
        
        MOV AH, 0     
        MOV AL, sati
        MOV BL, 10
        DIV BL              		; AL = rez , AH = ostatak 
        
        MOV trenutno_vreme[1], AH
        MOV trenutno_vreme[0], AL   
                    
        MOV AH, 0                    
        MOV AL, min
        DIV BL              		; AL = rez , AH = ostatak 
        
        MOV trenutno_vreme[4], AH
        MOV trenutno_vreme[3], AL  
           
        MOV AH, 0        
        MOV AL, sec
        DIV BL              		; AL = rez , AH = ostatak 
        
        MOV trenutno_vreme[7], AH
        MOV trenutno_vreme[6], AL
            
	RET
formiraj_vreme EndP 


   
;****************************************************************************************************	
;Procedura koja cita novac i smesta u suma
;****************************************************************************************************
procitaj_novac Proc Near   
        MOV AL, 01h      	; u AL upisemo vrednost    01 DA BI UNEO READ SIGNAL U UREDJAJ ZA NOVAC
        MOV DX, PA8255 		; u DX ide adresa porta a iz 8255
        OUT DX, AL		; upise se vrednost
	MOV AL, 00010000b
	MOV DX, PC8255
	OUT DX, AL
     	CALL cekaj_1msec     	; cekaj 1ms sacekaj prekid
	MOV AL, 00000000b
	MOV DX, PC8255
	OUT DX, AL		;ukini OE signal	
	        	                                                  

     	MOV DX, PC8255      
     	IN  AL, DX          	; PC6,PC5,PC4  0 x x x 0 0 0 0
     	AND AL, 01110000b   	; PC6,PC5,PC4  0 x x x 0 0 0 0
        SHR AL, 4           	; PC6,PC5,PC4  0 0 0 0 0 x x x
        
        CMP AL, 1           	; suma+=10
        JNE CON2  
        MOV BX, suma
        ADD BX, 10
        MOV suma, BX
        JMP CON8
        
CON2:   CMP AL, 2           	; suma+=20
        JNE CON3  
        MOV BX, suma
        ADD BX, 20
        MOV suma, BX
        JMP CON8
        
CON3:   CMP AL, 3           	; suma+=50
        JNE CON4  
        MOV BX, suma
        ADD BX, 50
        MOV suma, BX
        JMP CON8
        
CON4:   CMP AL, 4          	; suma+=100
        JNE CON5  
        MOV BX, suma
        ADD BX, 100
        MOV suma, BX
        JMP CON8   
        
CON5:   CMP AL, 5           	; suma+=200
        JNE CON6  
        MOV BX, suma
        ADD BX, 200
        MOV suma, BX
        JMP CON8
        
CON6:   CMP AL, 6           	; nema_novcanica=1 , nije vracena novcanica
        JNE CON7  
        MOV nema_novcanica,1
        JMP CON8  
        
CON7:   CMP AL, 7           	; suma-=novcanica_izbacena , vracena novcanica
        JNE CON8  
        MOV BX, suma
        SUB BX, novcanica_izbacena
        MOV suma, BX  
        			          
        RET
procitaj_novac EndP
 
;****************************************************************************************************	
;Prekid sa automata za novac
;****************************************************************************************************
novacInt Proc far 
        PUSHA    

	CALL procitaj_novac      
           		        
KRAJM:  POPA
        IRET
novacInt EndP

 
;****************************************************************************************************	
;Prekid sa spirale
;****************************************************************************************************
spiralaInt Proc far 
        PUSHA    

	MOV AL, 1				
	MOV kupljen_proizvod, AL
	MOV AL, 00000000b			;zaustavljanje motora
	MOV DX, PA8255
	OUT DX, AL
	MOV Al, 00000001b
	MOV DX, PC8255
	OUT DX, AL
	MOV AL, 00h
	OUT DX, AL      
           		        
KRAJM:  POPA
        IRET
spiralaInt EndP 


;****************************************************************************************************	
;Dohvati kod sa tastature
;****************************************************************************************************
dohvatiTaster Proc Near  

	MOV AH, 000000111b			;skeniranje tastature
	MOV DX, PA8255
	OUT DX, AH
	MOV AH, 00000011b
	MOV DX, PC8255
	OUT DX, AH
	MOV AH, 00h
	OUT DX, AH


	MOV DX, PB8255
	IN  AH, DX
	MOV BH, 00000111b
	MOV AL, 0
	CMP AH,BH
	JNE TAST1
	MOV tmpChar, AL
	JMP ENDRD
TAST1:	MOV BH, 00001011b
	MOV AL, 1
	CMP AH,BH
	JNE TAST2
	MOV tmpChar, AL
	JMP ENDRD
TAST2:	MOV BH, 00001101b
	MOV AL, 2
	CMP AH,BH
	JNE TAST3
	MOV tmpChar, AL
	JMP ENDRD
TAST3:	MOV BH, 00001101b
	MOV AL, 3
	CMP AH,BH
	JNE TAST10
	MOV tmpChar, AL
	JMP ENDRD	
TAST10:	MOV AH, 000001011b
	MOV DX, PA8255
	OUT DX, AH
	MOV AH, 00000011b
	MOV DX, PC8255
	OUT DX, AH
	MOV AH, 00h
	OUT DX, AH
	MOV DX, PB8255
	IN  AH, DX
	MOV BH, 00000111b
	MOV AL, 4
	CMP AH,BH
	JNE TAST11
	MOV tmpChar, AL
	JMP ENDRD
TAST11:	MOV BH, 00001011b
	MOV AL, 5
	CMP AH,BH
	JNE TAST12
	MOV tmpChar, AL
	JMP ENDRD
TAST12:	MOV BH, 00001101b
	MOV AL, 6
	CMP AH,BH
	JNE TAST13
	MOV tmpChar, AL
	JMP ENDRD
TAST13:	MOV BH, 00001101b
	MOV AL, 7
	CMP AH,BH
	JNE TAST20
	MOV tmpChar, AL
	JMP ENDRD
TAST20:	MOV AH, 000001101b
	MOV DX, PA8255
	OUT DX, AH
	MOV AH, 00000011b
	MOV DX, PC8255
	OUT DX, AH
	MOV AH, 00h
	OUT DX, AH
	MOV DX, PB8255
	IN  AH, DX
	MOV BH, 00000111b
	MOV AL, 8
	CMP AH,BH
	JNE TAST21
	MOV tmpChar, AL
	JMP ENDRD
TAST21:	MOV BH, 00001011b
	MOV AL, 9
	CMP AH,BH
	JNE TAST22
	MOV tmpChar, AL
	JMP ENDRD
TAST22:	MOV BH, 00001101b
	MOV AL, 10
	CMP AH,BH
	JNE TAST23
	MOV tmpChar, AL
	JMP ENDRD
TAST23:	MOV BH, 00001101b
	MOV AL, 11
	CMP AH,BH
	JNE TAST30
	MOV tmpChar, AL
	JMP ENDRD	
TAST30:	MOV AH, 00001110b
	MOV DX, PA8255
	OUT DX, AH
	MOV AH, 00000011b
	MOV DX, PC8255
	OUT DX, AH
	MOV AH, 00h
	OUT DX, AH
	MOV DX, PB8255
	IN  AH, DX
	MOV BH, 00000111b
	MOV AL, 12
	CMP AH,BH
	JNE TAST31
	MOV tmpChar, AL
	JMP ENDRD
TAST31:	MOV BH, 00001011b
	MOV AL, 13
	CMP AH,BH
	JNE TAST32
	MOV tmpChar, AL
	JMP ENDRD
TAST32:	MOV BH, 00001101b
	MOV AL, 14
	CMP AH,BH
	JNE TAST33
	MOV tmpChar, AL
	JMP ENDRD
TAST33:	MOV BH, 00001110b
	MOV AL, 15
	MOV tmpChar, AL            
ENDRD:	RET

dohvatiTaster EndP

;****************************************************************************************************	
;Procedura za vracanje kusura
;****************************************************************************************************
vratiKusur Proc Near    
    
WHILE:  MOV AX, suma   			 ;suma>=200 && no200==0   
        CMP AL, 200  
        JL  CON100
        MOV AL, no200
        CMP AL, 0
        JNE CON100     
        MOV novcanica_izbacena, 200   	
        MOV AL, 00010110b  		; u AL upisemo vrednost wr=1 , 5 podatak koji se upisuje
        MOV DX, PA8255 			; u DX ide adresa porta A iz 8255 
        OUT DX, AL			; upise se vrednost
	MOV AL, 00001000b
	MOV DX, PC8255			;zalecujemo vrednost
	OUT DX, AL
     	CALL cekaj_1msec     		; cekaj 1ms sacekaj prekid
	MOV AL, 00h			; odlecujemo
	OUT DX, AL
     	CALL procitaj_novac
     	MOV AL, nema_novcanica
     	CMP AL, 1
     	JNE NB200 
     	MOV no200, 1
NB200:  MOV nema_novcanica, 0
        JMP WHILE    
        
CON100: MOV AX, suma    		;suma>=100 && no100=0   
        CMP AL, 100  
        JL  CON50
        MOV AL, no100
        CMP AL, 0
        JNE CON50     
        MOV novcanica_izbacena, 100  
        MOV AL, 00010010b  		; u AL upisemo vrednost wr=1 , 4 podatak koji se upisuje
        MOV DX, PA8255 			; u DX ide adresa porta A iz 8255 
        OUT DX, AL			; upise se vrednost
	MOV AL, 00001000b
	MOV DX, PC8255			;zalecujemo vrednost
	OUT DX, AL
     	CALL cekaj_1msec     		; cekaj 1ms sacekaj prekid
	MOV AL, 00h			; odlecujemo
	OUT DX, AL
     	CALL procitaj_novac
     	MOV AL, nema_novcanica
     	CMP AL, 1
     	JNE NB100 
     	MOV no100, 1
NB100:  MOV nema_novcanica, 0
        JMP WHILE   
        
CON50:  MOV AX, suma    ;suma>=50 && no50==0   
        CMP AL, 50  
        JL  CON20
        MOV AL, no50
        CMP AL, 0
        JNE CON20     
        MOV novcanica_izbacena, 50  
        MOV AL, 00001110b  		; u AL upisemo vrednost wr=1 , 3 podatak koji se upisuje
        MOV DX, PA8255 			; u DX ide adresa porta A iz 8255 
        OUT DX, AL			; upise se vrednost
	MOV AL, 00001000b
	MOV DX, PC8255			;zalecujemo vrednost
	OUT DX, AL
     	CALL cekaj_1msec     		; cekaj 1ms sacekaj prekid
	MOV AL, 00h			; odlecujemo
	OUT DX, AL
     	CALL procitaj_novac
     	MOV AL, nema_novcanica
     	CMP AL, 1
     	JNE NB50 
     	MOV no50, 1
NB50:   MOV nema_novcanica, 0
        JMP WHILE 
        
CON20:  MOV AX, suma    ;suma>=20 && no20==0   
        CMP AL, 20  
        JL  CON10
        MOV AL, no20
        CMP AL, 0
        JNE CON10     
        MOV novcanica_izbacena, 20  
        MOV AL, 00001010b  		; u AL upisemo vrednost wr=1 , 2 podatak koji se upisuje
        MOV DX, PA8255 			; u DX ide adresa porta A iz 8255 
        OUT DX, AL			; upise se vrednost
	MOV AL, 00001000b
	MOV DX, PC8255			;zalecujemo vrednost
	OUT DX, AL
     	CALL cekaj_1msec     		; cekaj 1ms sacekaj prekid
	MOV AL, 00h			; odlecujemo
	OUT DX, AL
     	CALL procitaj_novac
     	MOV AL, nema_novcanica
     	CMP AL, 1
     	JNE NB20 
     	MOV no20, 1
NB20:   MOV nema_novcanica, 0
        JMP WHILE  
        
CON10:  MOV AX, suma    ;suma>=10   
        CMP AL, 10  
        JL  CON0     
        MOV novcanica_izbacena, 10  
        MOV AL, 00000110b  		; u AL upisemo vrednost wr=1 , 1 podatak koji se upisuje
        MOV DX, PA8255 			; u DX ide adresa porta A iz 8255 
        OUT DX, AL			; upise se vrednost
	MOV AL, 00001000b
	MOV DX, PC8255			;zalecujemo vrednost
	OUT DX, AL
     	CALL cekaj_1msec     		; cekaj 1ms sacekaj prekid
	MOV AL, 00h			; odlecujemo
	OUT DX, AL
     	CALL procitaj_novac
     	MOV AL, nema_novcanica
     	CMP AL, 1
     	JNE WHILE    
     	MOV AL, noChan 
     	MOV poruka, AL       
        CALL ispisiPorukuNaDispleju
        JMP KRAJC 
        
CON0:   MOV AX, suma    ;suma==0   
        CMP AL, 0  
        JNE WHILE  
        MOV AL, uzmiteK 
        MOV poruka, AL  
        CALL ispisiPorukuNaDispleju 
        MOV currState, STARTNO_STANJE
        JMP KRAJC
        
KRAJC:  MOV no200, 0        ;vrati indikatore na 0                  
        MOV no100, 0 
        MOV no50, 0 
        MOV no20, 0 
        MOV no10, 0             
        RET
vratiKusur EndP

   
;****************************************************************************************************	
;Procedura meri duzinu niza
;****************************************************************************************************
izracunajDuzinuProc Near 
        MOV CX, 19
label1: MOV BX, CX
        MOV AL, poruka[BX]
        CMP AL, ' '
        LOOPE label1
        MOV len, BL   
        RET 
izracunajDuzinuEndP

 
;****************************************************************************************************	
;Procedura ispisuje poruku na display
;****************************************************************************************************
ispisiPorukuNaDispleju Proc Near 
        MOV DX, 0           ;i iteraciona promenljiva
        CALL izracunajDuzinu       ;smesta duzinu u len
        MOV trenutna_poruka[0], ' '
        MOV trenutna_poruka[1], ' ' 
        MOV trenutna_poruka[2], ' ' 
        MOV trenutna_poruka[3], ' ' 
        MOV trenutna_poruka[4], ' ' 
        MOV trenutna_poruka[5], ' ' 
        MOV trenutna_poruka[6], ' ' 
        MOV trenutna_poruka[7], ' '
        
        MOV CH, len 
        ADD CH, 8
        MOV CL, 7  
        
FORi:   CMP DH,CH
        JE  KRAJIP 
        MOV AL, sec
WHILE1S:CMP AL, sec
        JE WHILE1S 
        
        MOV DL, 0           ;j iteraciona promenljiva 
FORj:   CMP DL,CL
        JE  KRAJFJ 
        INC DL 
        MOV BH, 0
        MOV BL, DL           ;DL se stavlja u BX zbog indeksiranja
        MOV AL, trenutna_poruka[BX]
        DEC DL  
        MOV BH, 0
        MOV BL, DL           ;DL se stavlja u BX zbog indeksiranja
        MOV trenutna_poruka[BX], AL
        INC DL
        JMP FORj  
        
KRAJFJ: CMP DH, len
        JL LABI
        MOV trenutna_poruka[7], ' '
        INC DH
        JMP FORi
LABI:   MOV BH, 0
        MOV BL, DH           ;DL se stavlja u BX zbog indeksiranja
        MOV AH, poruka[BX]
        MOV trenutna_poruka[7], AH
        INC DH
        JMP FORi       
KRAJIP: RET 
ispisiPorukuNaDispleju EndP


 
;****************************************************************************************************	
;Prekid sa tastature
;**************************************************************************************************** 
tastaturaInt Proc far 
        CLI  
        PUSHA                                                           
        
	CALL dohvatiTaster      	;smesti u tmpChar karakter procitan sa tastature
		
DEL:	MOV AL, tempchar		;ako je pritisnut taster del 
	CMP AL, 11
	JNE ENTER
	MOV CL, uneto_cifara		;i ako je broj unetih cifara = 0 
	CMP CL, 0			;ne radi nista
	JE KRAJT		 
	CMP CL, 1			;ako je broj unetih cifara = 1 
	JNE DEL1
	MOV BH, ' '
	MOV cifra1, BH			;u prvu cifru upisi prazninu
	JMP DEL1
	CMP CL, 2			;a ako je uneto 2 cifre u drugu cifru pisi prazninu
	JNE KRAJT
	MOV BH,' '
	MOV cifra2, BH	
DEL1:	DEC CL				;i smanji broj unetih cifara za jedan
	MOV uneto_cifara, CL 
ENTER:	CMP AL, 10			;ako je pritisnut taster enter
	JNE CHANGE
	MOV CL, uneto_cifara
	CMP CL, 2
	JNE KRAJT
	MOV AL, cifra1        		;cifra1*10+cifra2
        MOV BL, 10
        MUL BL
        ADD AL, cifra2
        MOV BX, AX			;poredjenje cene proizvoda i kolicine unetog novca
        MOV AH, 0
	MOV AL, cenaProizvoda[BX]
	MOV CX, suma
	CMP AX, CX
	MOV CL, nesaloP
	mov poruka, CL
	CALL ispisiPorukuNaDispleeju	;ispisivanje poruke da nije uneto dovoljno para
	MOV AX, BX
	MOV DX, PA8255			;pokretanje motora
	OUT DX, AL
	MOV AL, 00000001b
	MOV DX, PC8255
	OUT DX, AL
	MOV AL, 00000000b
	MOV DX, PC8255
	OUT DX, AL		
	MOV AX, sec			;cekaj 6 sekundi
	ADD AX, 6
WAIT:	CMP AX, sec
	JGE WAIT
	MOV AL, kupljenProizvod
	CMP AL, 1
	JNE ENTER1
	MOV CX, suma
	DEC CX, cenaProizvoda[BX]
	MOV suma, CX
	MOV AX, zaradaProizvoda[BX]
	ADD AX, cenaProizvoda[BX]
	MOV zaradaProizvoda[BX], AX	;uracunaj zaradu po proizvodu
	mov AX, suma
	CMP AX, 0
	JNE ENTER2
	MOV CL, zahvalnost
	mov poruka, CL
	CALL ispisiPorukuNaDispleeju	;ispisivanje poruke o zahvalnosti
	CALL pocetnoStanje
	JMP KRAJT
	MOV CL, uzmiteK
	mov poruka, CL
ENTER2: CALL ispisiPorukuNaDispleju	;ispisivanje poruke o uzimanju kusura
	JMP KRAJT
	MOV AH, nestaloP
	mov poruka, AH 
ENTER1: CALL ispisiPorukuNaDispleju	;ispisivanje poruke o nepostojanju proizvoda
	JMP KRAJT 	
CHANGE:	MOV AL, tempchar		;pritisnut taster za kusur
	CMP AL, 12
	JNE DEFAULT
	MOV CL, kupljenProizvod		;ako je proizvod kupljen
	CMP CL, 1
	JNE KRAJT
	mov CX, suma			;i ostatak novca manji od 200
	MOV CX, 200
	JG KRAJT
	CALL vratiKusur			;vrati kusur 
	CALL pocetnoStanje		;i predji na pocetno stanje
	JMP KRAJT
DEFAULT:MOV AL, uneto_cifara
	CMP AL, 2
	JGE KRAJT
	CALL formirajIspis
	INC AL
	MOV uneto_cifara, AL
	CMP AL, 1
	JNE
	MOV BL, 1
	MOV prikazuje_vip, BL
	JMP KRAJT 
DEFAULT1:MOV AL, cifra1        		;cifra1*10+cifra2
        MOV BL, 10
        MUL BL
        ADD AL, cifra2
        MOV BX, AX
	MOV CL, nazivProizvoda[bx]
	mov poruka, CL	
	CALL ispisiPorukuNaDispleju		      	      	   
KRAJT:  POPA
        STI
        IRET
tastaturaInt EndP

    
;****************************************************************************************************	
;Prekid sa serijskog porta - Transmit
;****************************************************************************************************
serialTransmitInt Proc far 
        CLI  
        PUSHA                                                           
		
        MOV AL, Hpromet   	; u AL se smesta podatak koji se salje
        MOV DX, DAT8251 	; u DX adresa registra podataka u koji se upisuje
        OUT DX, AL 		    ; upis podatka u 8251  
        MOV currState, STARTNO_STANJE
        MOV broj_poruke, 0 
                        	      	   	   		        
        POPA
        STI
        IRET
serialTransmitInt EndP

 
;****************************************************************************************************	
;Prekid sa serijskog porta - Receive
;****************************************************************************************************
serialReceiveInt Proc far 
        CLI  
        PUSHA     
                                                              
        				;CL = msg
        
        MOV DX, DAT8251 		; adresa registra podataka 8251						
        IN AL, DX 			; citamo podatak iz 8251
        MOV CL, AL
        
        MOV AL, broj_poruke     	;if(broj_poruke==0)
        CMP AL, 0
        JNE SWITCHS   
        
        CMP CL, PROCITAJ_PROMET_P     	;if(msg==RESETUJ_PROMET_U)
        JNE CIF0            
                
        MOV BX, 0
        
FOR0:   CMP BL, 100         		;resetovanje prometa po proizvodu
        JGE CIF0
        MOV zaradaProizvoda[BX], 0
        INC BX
        JMP FOR0
        JMP CONPP 
        
CIF0:   CMP CL, PROCITAJ_PROMET_P     	;else if(msg==PROCITAJ_PROMET_P)
        JNE CONPP         
        
        MOV promet_u, 0        		;ukupan promet svih proizvoda    resetovan
        MOV BX, 0   
        
FOR1:   CMP BL, 100          		;procitaj ukupan promet
        JGE CFOR1
        MOV AX, promet_u 
        ADD AX, zaradaProizvoda[BX] 
        MOV promet_u, AX 
        INC BX
        JMP FOR1
        
CFOR1:  MOV AX, promet_u          
        MOV Hpromet, AH
        MOV DX, DAT8251 		; u DX adresa registra podataka u koji se upisuje
        OUT DX, AL 		    	; upis podatka u 8251
        
CONPP:  MOV AL, broj_poruke
        INC AL
        MOV broj_poruke, AL
        MOV currState, CL        
                       	      	   
SWITCHS:MOV AL, currState
        CMP AL, POSTAVI_NAZIV_CENU
        JE  LPOSTAVI_NAZIV_CENU
        CMP AL, POSTAVI_CENU
        JE  LPOSTAVI_CENU
        CMP AL, RESETUJ_PROMET_P
        JE  LRstSPT 
        CMP AL, PODESAVANJE_VREMENA
        JE  LSetT  
        CMP AL, PROCITAJ_PROMET_U
        JE  LmRSPT

LPOSTAVI_NAZIV_CENU:MOV AL, broj_poruke       ;if(broj_poruke==1)
        CMP AL, 1
        JNE CIF1    
        MOV broj_proizvoda, CL        	;broj_proizvoda = poruka
        MOV AL, broj_poruke       	;broj_poruke++
        INC AL
        MOV broj_poruke, AL
        JMP KRAJSPR  
        
CIF1:   MOV AL, broj_poruke       	;else if(broj_poruke>=2 && broj_poruke<=17)
        CMP AL, 18
        JE CIF2         
        
        MOV AL, broj_proizvoda        	;nazivProizvoda[broj_proizvoda][broj_poruke-2]=msg
        MOV BL, 20
        MUL BL           
        MOV BX, AX          
                    
        MOV DH, 0                    
        MOV DL, broj_poruke        
        MOV DI, DX
        SUB DI, 2        
        MOV nazivProizvoda[BX+DI], CL         
        
        MOV AL, broj_poruke       	;nazivProizvoda[broj_proizvoda][broj_poruke-2] + y/n
        CMP AL, 17
        JNE CPI
        INC DI   
        MOV nazivProizvoda[BX+DI], ' ' 
        INC DI   
        MOV nazivProizvoda[BX+DI], 'Y'
        INC DI   
        MOV nazivProizvoda[BX+DI], '/'
        INC DI   
        MOV nazivProizvoda[BX+DI], 'N'
         
        
CPI:    MOV AL, broj_poruke   		;broj_poruke++
        INC AL
        MOV broj_poruke, AL
        JMP KRAJSPR
        
CIF2:   MOV BH, 0           		;else    postavljanje cene 
        MOV BL, broj_proizvoda          
        MOV cenaProizvoda[BX], CL   	;u cl je poruka koja se prosledjuje
        MOV currState, STARTNO_STANJE
        MOV broj_poruke, 0                                
        JMP KRAJSPR
        


LPOSTAVI_CENU:MOV AL, broj_poruke       ;if(broj_poruke==1)
        CMP AL, 1
        JNE CIF3            		;postavljanje broja proizvoda 
        MOV broj_proizvoda, CL
        MOV AL, broj_poruke
        INC AL
        MOV broj_poruke, AL         
        JMP KRAJSPR 
        
CIF3:   MOV BH, 0           		;else 
        MOV BL, broj_proizvoda          
        MOV cenaProizvoda[BX], CL       ;postavljanje cene za tekuci broj prizvoda
        MOV currState, STARTNO_STANJE
        MOV broj_poruke, 0        
        JMP KRAJSPR  
        


LRstSPT:MOV AL, broj_poruke      	 ;if(broj_poruke==1)    resetovanje zarade za proizvod
        CMP AL, 1
        JNE KRAJSPR    
        MOV broj_proizvoda, CL
        MOV BH, 0
        MOV BL, broj_proizvoda
        MOV zaradaProizvoda[BX], 0
        MOV currState, STARTNO_STANJE
        MOV broj_poruke, 0          
        JMP KRAJSPR  
        


LSetT:  MOV AL, broj_poruke       	;if(broj_poruke==1)    podesavanje vremena!!!
        CMP AL, 1
        JNE CIF4
        MOV sec, CL        		 ;podesavanje sekundi
        MOV AL, broj_poruke       	;broj_poruke++
        INC AL
        MOV broj_poruke, AL
        JMP KRAJSPR
        
CIF4:   MOV AL, broj_poruke       	;else if(broj_poruke==2)
        CMP AL, 2
        JNE CIF5
        MOV min, CL        		;podesavanje minuta
        MOV AL, broj_poruke       	;broj_poruke++
        INC AL
        MOV broj_poruke, AL
        JMP KRAJSPR 
        
CIF5:   MOV sati, CL         ;else
        MOV currState,STARTNO_STANJE 	;podesavanje sati
        MOV broj_poruke, 0 
        JMP KRAJSPR  
        
LmRSPT: MOV broj_proizvoda, CL        	;citanje prometa za zadati proizvod
        MOV BH, 0
        MOV BL, broj_proizvoda
        MOV AX, zaradaProizvoda[BX]          
        MOV Hpromet, AH
        MOV DX, DAT8251 		; u DX adresa registra podataka u koji se upisuje
        OUT DX, AL                                     
                           
KRAJSPR:POPA
        STI
        IRET
serialReceiveInt EndP

   
;****************************************************************************************************	
;Glavni Program
;****************************************************************************************************
START:  ;inicijalizacija segmentnih registara i SP-a
    	XOR AX, AX
    	MOV DS, AX
    	MOV ES, AX
    	MOV SS, AX
    	MOV SP, 0500h
    														
    	; inicijalizacija vektora za prekide od 8259A								
    	MOV AX, OFFSET countTimeInt				; Timer 0 za brojnje vremena			
        MOV I8259, AX											
        MOV AX, SEG countTimeInt								
        MOV I8259+2, AX											
    															
    	MOV AX, OFFSET serialReceiveInt	        		; Serijski port - prijem						
        MOV I8259+4, AX											
        MOV AX, SEG serialReceiveInt								
        MOV I8259+6, AX											
    															
    	MOV AX, OFFSET tastaturaInt              		; Prekid sa tastature							
        MOV I8259+8, AX											
        MOV AX, SEG tastaturaInt								
        MOV I8259+10, AX										
    															
    	MOV AX, OFFSET moneyInt                 		; Prekid sa automata za novac								
        MOV I8259+12, AX										
        MOV AX, SEG moneyInt									
        MOV I8259+14, AX										
    															
    	MOV AX, OFFSET serialTransmitInt        		; Serijski port - slanje						
        MOV I8259+16, AX										
        MOV AX, SEG serialTransmitInt							
        MOV I8259+18, AX										
    															
    	MOV AX, OFFSET timet11Int	            		; Timer 1 za odziv automata za novac					
        MOV I8259+24, AX										
        MOV AX, SEG timer1Int							
        MOV I8259+26, AX
	
	MOV AX, OFFSET spiral1Int	            		; Prekid od spirale					
        MOV I8259+28, AX										
        MOV AX, SEG spiral1Int							
        MOV I8259+30, AX

																																																		
    															
    	; inicijalizacija periferija											
        CALL init8251											
    	CALL init8254											
    	CALL init8259												
    	CALL init8255											
																								
forever:NOP													
	    JMP forever												
program ENDS	
											
end START	